﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Deployment.Application;
using System.Collections.Specialized;
using System.Web;
using System.IO;
using System.Windows;
using System.Net;

namespace jKinect.Browser
{
    public class Constants
    {
        public const string WEBKINECT_EXT = ".webkinect";
        public const string WEBKINECT_URL = "URL";
        public const string WEBKINECT_KXPATCH = "KXPatchURL";

    }
    public class jKinectExperienceParameter
    {
        public string WebAppUrl { get; set; }
        public string KXPatch { get; set; }

        public static jKinectExperienceParameter GetCurrentParameters()
        {
            jKinectExperienceParameter KXParameters = new jKinectExperienceParameter();
            string[] commandLineArgs = Environment.GetCommandLineArgs();
            //manual commandline parameters
            if (commandLineArgs != null && commandLineArgs.Length > 1)
            {
                KXParameters.WebAppUrl = commandLineArgs[1];
                if (commandLineArgs.Length > 2)
                    KXParameters.KXPatch = commandLineArgs[2];
            }
            // ClickOnce url parameters
            else if (ApplicationDeployment.IsNetworkDeployed)
            {
                //if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments != null)
                //{
                if (ApplicationDeployment.CurrentDeployment.ActivationUri != null
                    && !string.IsNullOrWhiteSpace(ApplicationDeployment.CurrentDeployment.ActivationUri.Query))
                {
                    NameValueCollection nameValueTable = GetQueryStringParameters();
                    if (nameValueTable != null && nameValueTable.Count > 0)
                    {
                        if (!string.IsNullOrEmpty(nameValueTable[Constants.WEBKINECT_URL]))
                            KXParameters.WebAppUrl = nameValueTable[Constants.WEBKINECT_URL];
                        if (!string.IsNullOrEmpty(nameValueTable[Constants.WEBKINECT_KXPATCH]))
                            KXParameters.KXPatch = nameValueTable[Constants.WEBKINECT_KXPATCH];
                    }
                }
                else
                    // Click once commandline parameters
                    if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null
                        && AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Length > 0
                        //clickonce app send the .app filename if no other parameter
                        && !AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0].EndsWith(".application"))
                    {
                        KXParameters.WebAppUrl = new Uri(AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0]).LocalPath;
                        // if one day we succeed sending multiple parameter to clickonce
                        if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Length > 1
                            && AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[1].ToLower().EndsWith(".js"))
                            KXParameters.KXPatch = new Uri(AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[1]).LocalPath;
                    }
                //}
            }
            if (!string.IsNullOrEmpty(KXParameters.WebAppUrl)
                &&
                (KXParameters.WebAppUrl.ToLower().EndsWith(Constants.WEBKINECT_EXT) || KXParameters.WebAppUrl.ToLower().EndsWith(".url"))
                )
                KXParameters = ExtractWebkinectData(KXParameters.WebAppUrl);

            return AbsolutiseParametersPath(KXParameters);
        }

        public static jKinectExperienceParameter AbsolutiseParametersPath(jKinectExperienceParameter KXParameters)
        {
            if (!string.IsNullOrEmpty(KXParameters.WebAppUrl) && !KXParameters.WebAppUrl.ToLower().StartsWith("http"))
            {
                if (File.Exists(KXParameters.WebAppUrl.Replace("file:///", "")))
                    // use full path in case commandLineArg is a relative path
                    KXParameters.WebAppUrl = new FileInfo(KXParameters.WebAppUrl.Replace("file:///", "")).FullName;
                else
                    MessageBox.Show("Unable to find " + KXParameters.WebAppUrl, "WebApp not found", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            if (!string.IsNullOrEmpty(KXParameters.KXPatch) && !KXParameters.KXPatch.ToLower().StartsWith("http"))
            {
                if (File.Exists(KXParameters.KXPatch))
                    // use full path in case commandLineArg is a relative path
                    KXParameters.KXPatch = new FileInfo(KXParameters.KXPatch).FullName;
                else
                    MessageBox.Show("Unable to find " + KXParameters.KXPatch, "Kinect Experience Patch not found", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            return KXParameters;
        }

        public static jKinectExperienceParameter ExtractWebkinectData(string webkinect)
        {
            bool isFromTheWeb = false;
            string webkinectFile = webkinect;
            jKinectExperienceParameter KXParameters = new jKinectExperienceParameter();
            try
            {

                if (Uri.IsWellFormedUriString(webkinectFile, UriKind.Absolute))
                {
                    if (new Uri(webkinectFile).IsFile)
                        webkinectFile = new Uri(webkinectFile).LocalPath;
                    else
                    {
                        WebClient wc = new WebClient();
                        string downloadedFile = System.IO.Path.GetTempFileName();
                        wc.DownloadFile(webkinectFile, downloadedFile);
                        isFromTheWeb = true;
                        webkinectFile = downloadedFile;
                    }
                }

                if (File.Exists(webkinectFile))
                {
                    string[] lines = File.ReadAllLines(webkinectFile);
                    foreach (string line in lines)
                    {
                        if (line.StartsWith(Constants.WEBKINECT_URL + "="))
                            KXParameters.WebAppUrl = line.Replace(Constants.WEBKINECT_URL + "=", "");
                        if (line.StartsWith(Constants.WEBKINECT_KXPATCH + "="))
                            KXParameters.KXPatch = line.Replace(Constants.WEBKINECT_KXPATCH + "=", "");
                    }
                }
                else
                    throw new FileNotFoundException("Unable to find " + KXParameters.WebAppUrl);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "WEBKINECT file not found", MessageBoxButton.OK, MessageBoxImage.Error);
            }

            // check if it's a file
            if (!string.IsNullOrEmpty(KXParameters.WebAppUrl) && !KXParameters.WebAppUrl.Contains(":"))// not an existing absolute path
            {
                if (isFromTheWeb)
                {
                    KXParameters.WebAppUrl = new Uri(new Uri(webkinect), KXParameters.WebAppUrl).ToString();
                }
                else
                {
                    KXParameters.WebAppUrl = Path.Combine(new FileInfo(webkinectFile).DirectoryName, KXParameters.WebAppUrl);
                }
            }

            // check if it's a file 
            if (!string.IsNullOrEmpty(KXParameters.KXPatch) && !KXParameters.KXPatch.Contains(";"))// not an existing absolute path
            {
                if (isFromTheWeb)
                {
                    KXParameters.KXPatch = new Uri(new Uri(webkinect), KXParameters.KXPatch).ToString();
                }
                else
                {
                    KXParameters.KXPatch = Path.Combine(new FileInfo(webkinectFile).DirectoryName, KXParameters.KXPatch);
                }
            }

            return KXParameters;
        }

        private static NameValueCollection GetQueryStringParameters()
        {
            NameValueCollection nameValueTable = null;

            string queryString = ApplicationDeployment.CurrentDeployment.ActivationUri.Query.TrimStart('?');
            nameValueTable = new HttpValueCollection(queryString, true);
            return nameValueTable;
        }

    }
}
